home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / utility / mu17_ext.zip / RLOGIN.C < prev    next >
C/C++ Source or Header  |  1994-03-07  |  13KB  |  477 lines

  1. /*
  2. **    $VER: rlogin.c 1.1 (08.02.94)
  3. **
  4. **    remote login command
  5. **
  6. **    ⌐ Copyright 1994 by Norbert Pⁿschel
  7. **    All Rights Reserved
  8. */
  9.  
  10. #include <proto/exec.h>
  11. #include <proto/dos.h>
  12. #include <clib/envoy_protos.h>
  13. #include <pragmas/envoy_pragmas.h>
  14. #include <clib/nipc_protos.h>
  15. #include <pragmas/nipc_pragmas.h>
  16. #include <clib/services_protos.h>
  17. #include <pragmas/services_pragmas.h>
  18. #include <clib/alib_stdio_protos.h>
  19.  
  20. #include <exec/memory.h>
  21. #include <devices/conunit.h>
  22. #include <dos/dosextens.h>
  23. #include <envoy/envoy.h>
  24.  
  25. #include <string.h>
  26.  
  27. #include <debug.h>
  28.  
  29. struct Library *NIPCBase;
  30. struct Library *ServicesBase;
  31. struct Library *EnvoyBase;
  32.  
  33. long __oslibversion = 37;
  34.  
  35. const UBYTE version[] = "$VER: rlogin 1.1 " __AMIGADATE__ ;
  36.  
  37. UBYTE template[] = "HOST,USERID,GUI/S";
  38. LONG args[3];
  39.  
  40. #define HBUFFLEN   256
  41. #define UBUFFLEN   32
  42. #define PWDBUFFLEN 16
  43.  
  44. #ifdef LATTICE
  45. #ifndef __SASC_60
  46. int CXBRK(void)     { return(0); }  /* Disable Lattice CTRL/C handling */
  47. void chkabort(void) { return; }     /* really */
  48. #else
  49. void _CXBRK(void) {}
  50. #endif
  51. #endif
  52.  
  53. void killnl(STRPTR s)
  54.  
  55. {
  56.   while(*s && *s != '\n' && *s != '\r') s++;
  57.   *s = '\0';
  58. }
  59.  
  60. BOOL out(STRPTR s)
  61.  
  62. {
  63.   LONG l = strlen(s);
  64.  
  65.   return((BOOL)(Write(Output(),s,l) == l));
  66. }
  67.  
  68. BOOL in(STRPTR s,LONG l)
  69.  
  70. {
  71.   LONG r;
  72.  
  73.   r = Read(Input(),s,l-1);
  74.   if(r > -1) {
  75.     s[r] = '\0';
  76.     return(TRUE);
  77.   }
  78.   else return(FALSE);
  79. }
  80.  
  81. BOOL rawin(STRPTR s,LONG l)
  82.  
  83. {
  84.   LONG len = 0;
  85.  
  86.   BPTR input = Input();
  87.   BPTR output = Output();
  88.   BOOL done = FALSE;
  89.  
  90.   SetMode(input,1);
  91.  
  92.   l--;
  93.  
  94.   while(len < l && !done) {
  95.     if(Read(input,s,1) != 1) break;
  96.     switch(*s) {
  97.       case '\b':
  98.         if(len) {
  99.           Write(output,"\b",1);
  100.           len--;
  101.           s--;
  102.         }
  103.         break;
  104.       case '\n':
  105.       case '\r':
  106.         done = TRUE;
  107.       default:
  108.         if(((*s & 0x7F) > 31 || *s == '\n' || *s == '\r') && *s != 127) {
  109.           Write(output," ",1);
  110.           len++;
  111.           s++;
  112.         }
  113.         else {
  114.           Write(output,"\007",1); /* bell */
  115.         }
  116.         break;
  117.     }
  118.   }
  119.   Write(output,"\n",1);
  120.   if(len == l) done = TRUE;
  121.   *s = '\0';
  122.   SetMode(input,0);
  123.   return(done);
  124. }
  125.  
  126. #define req(trans,n) (void *)(((UBYTE *)(trans->trans_RequestData))+(n))
  127. #define resp(trans,n) (void *)(((UBYTE *)(trans->trans_ResponseData))+(n))
  128.  
  129. #define OFFS_CONUNIT  0
  130. #define SIZE_CONUNIT  14*sizeof(WORD)
  131. #define OFFS_RES1     OFFS_CONUNIT+SIZE_CONUNIT
  132. #define SIZE_RES1     sizeof(LONG)
  133. #define OFFS_RES2     OFFS_RES1+SIZE_RES1
  134. #define SIZE_RES2     sizeof(LONG)
  135. #define OFFS_RESPDATA OFFS_RES2+SIZE_RES2
  136.  
  137. #define OFFS_ARG1     0
  138. #define SIZE_ARG1     sizeof(LONG)
  139. #define OFFS_ARG2     OFFS_ARG1+SIZE_ARG1
  140. #define SIZE_ARG2     sizeof(LONG)
  141. #define OFFS_REQDATA  OFFS_ARG2+SIZE_ARG2
  142.  
  143. #define CONUNIT(ci) (APTR)&(((struct ConUnit *)(ci.ci_IOStdReq->io_Unit))->cu_XCP)
  144.  
  145. struct ConInfo {
  146.   struct MinList   ci_Actions;
  147.   BOOL             ci_IsOpen;
  148.   struct Entity   *ci_Dest;
  149.   struct Entity   *ci_Source;
  150.   struct MsgPort  *ci_Handler;
  151.   struct MsgPort  *ci_Port;
  152.   struct IOStdReq *ci_IOStdReq;
  153. } ci;
  154.  
  155. void do_packet(struct DosPacket *dp);
  156.  
  157. void do_transaction(struct Transaction *trans);
  158.  
  159. int main(int argc,char **argv) 
  160.  
  161. {
  162.   UBYTE hname[HBUFFLEN];
  163.   UBYTE uname[UBUFFLEN];
  164.   UBYTE pwd[PWDBUFFLEN];
  165.   int retval,rc2 = ERROR_NO_FREE_STORE;
  166.  
  167.   UBYTE ename[32];
  168.   BYTE signum;
  169.   ULONG mask,rmask;
  170.  
  171. #define bmask \
  172.         (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)
  173.  
  174.   struct Transaction *trans;
  175.  
  176.   struct Message *msg;
  177.   struct DosPacket *dp;
  178.   struct InfoData *id;
  179.  
  180.   struct RDArgs *rda;
  181.  
  182.   if(argc == 0) return(20); /* no WB ! */
  183.  
  184.   rda = ReadArgs(template,args,0);
  185.   if(rda == 0) return(10);
  186.     
  187.   if(args[0]) { /* host given */
  188.     strncpy(hname,(STRPTR)(args[0]),HBUFFLEN);
  189.   }
  190.   
  191.   if(args[1]) { /* user given */
  192.     strncpy(uname,(STRPTR)(args[1]),UBUFFLEN);
  193.   }
  194.  
  195.   if(args[2]) {
  196.     EnvoyBase = OpenLibrary("envoy.library",37);
  197.     if(EnvoyBase) {
  198.       if(args[0] == 0) {
  199.         retval = 
  200.           HostRequest(HREQ_Buffer,hname,
  201.                       HREQ_BuffSize,HBUFFLEN,
  202.                       TAG_DONE) ? 0 : 5;
  203.       }
  204.       else retval = 0;
  205.       if(retval == 0) {
  206.         retval = 
  207.           LoginRequest(LREQ_NameBuff,uname,
  208.                        LREQ_NameBuffLen,UBUFFLEN,
  209.                        LREQ_PassBuff,pwd,
  210.                        LREQ_PassBuffLen,PWDBUFFLEN,
  211.                        TAG_DONE) ? 0 : 5;
  212.       }
  213.       CloseLibrary(EnvoyBase);
  214.     }
  215.     else retval = 20;
  216.   }
  217.   else {
  218.     if(args[0] == 0) {
  219.       retval = (out("Host    : ") && in(hname,HBUFFLEN)) ? 0 : 5;
  220.     }
  221.     else retval = 0;
  222.     if(retval == 0 && args[1] == 0) {
  223.       retval = (out("User    : ") && in(uname,UBUFFLEN)) ? 0 : 5;
  224.     }
  225.     else retval = 0;
  226.     if(retval == 0) { 
  227.       retval = (out("Password: \033[8m") &&
  228.                 rawin(pwd,PWDBUFFLEN) &&
  229.                 out("\033[28m")) ? 0 : 5;
  230.     }
  231.     if(retval == 0) {
  232.       killnl(hname);
  233.       killnl(uname);
  234.       killnl(pwd);
  235.     }
  236.     debug2("Password: %s\n",pwd);
  237.   }
  238.  
  239.   FreeArgs(rda);
  240.  
  241.   if(retval) {
  242.     out("Login failed.\n");
  243.     return(retval);
  244.   }
  245.  
  246.   if(!IsInteractive(Input()) || !IsInteractive(Output())) return(20);
  247.  
  248.   ci.ci_Handler = ((struct FileHandle *)(BADDR(Input())))->fh_Type;
  249.  
  250.   ci.ci_IOStdReq = 0;
  251.   id = (struct InfoData *)AllocMem(sizeof(struct InfoData),MEMF_PUBLIC);
  252.   if(id) {
  253.     if(DoPkt(ci.ci_Handler,ACTION_DISK_INFO,MKBADDR(id),0,0,0,0)) {
  254.       ci.ci_IOStdReq = (struct IOStdReq *)(id->id_InUse);
  255.     }
  256.     FreeMem(id,sizeof(struct InfoData));
  257.   }
  258.  
  259.   retval = 20;
  260.  
  261.   ci.ci_Port = CreateMsgPort();
  262.   if(ci.ci_Port) {
  263.     signum = AllocSignal(-1);
  264.     if(signum != -1) {
  265.       NIPCBase = OpenLibrary("nipc.library",39);
  266.       if(NIPCBase) {
  267.         ServicesBase = OpenLibrary("services.library",37);
  268.         if(ServicesBase) {
  269.           sprintf(ename,"Remote Login %ld",
  270.                   ((struct Process *)FindTask(0))->pr_TaskNum);
  271.           ci.ci_Source = CreateEntity(ENT_Name,ename,
  272.                                       ENT_Public,TRUE,
  273.                                       ENT_Signal,signum,
  274.                                       TAG_DONE);
  275.           if(ci.ci_Source) {
  276.             debug("Entity created\n");
  277.             ci.ci_Dest = FindService(*hname ? hname : 0,
  278.                                      "Remote Login",ci.ci_Source,
  279.                                      FSVC_UserName,uname,
  280.                                      FSVC_PassWord,pwd,
  281.                                      FSVC_Error,&rc2,
  282.                                      TAG_DONE);
  283.             
  284.             if(ci.ci_Dest) {
  285.               debug("Service found\n");
  286.               trans = AllocTransaction(TRN_AllocReqBuffer,
  287.                                        SIZE_CONUNIT+strlen(ename)+1,
  288.                                        TAG_DONE);
  289.               if(trans) {
  290.                 debug("Transaction allocated\n");
  291.                 if(ci.ci_IOStdReq) {
  292.                   trans->trans_Command = 1;
  293.                   CopyMem(CONUNIT(ci),req(trans,OFFS_CONUNIT),SIZE_CONUNIT);
  294.                 }
  295.                 strcpy((STRPTR)req(trans,SIZE_CONUNIT),ename);
  296.                 DoTransaction(ci.ci_Dest,ci.ci_Source,trans);
  297.                 retval = trans->trans_Error;
  298.                 FreeTransaction(trans);
  299.                 if(retval == 0) {
  300.                   NewList((struct List *)&(ci.ci_Actions));
  301.                   ci.ci_IsOpen = TRUE;
  302.  
  303.                   mask = (1L<<signum)|(1L<<ci.ci_Port->mp_SigBit)|bmask;
  304.  
  305.                   do {
  306.                     rmask = Wait(mask);
  307.                     if(rmask &= bmask) goto do_break;
  308.                     do {
  309.                       if(rmask = bmask & SetSignal(0,bmask)) {
  310.                       do_break:
  311.                         trans = AllocTransaction(TAG_DONE);
  312.                         if(trans) {
  313.                           trans->trans_Command = rmask>>12;
  314.                           BeginTransaction(ci.ci_Dest,ci.ci_Source,trans);
  315.                         }
  316.                       }
  317.                       if(msg = GetMsg(ci.ci_Port)) {
  318.                         dp = (struct DosPacket *)(msg->mn_Node.ln_Name);
  319.                         do_packet(dp);
  320.                       }
  321.                       if(trans = GetTransaction(ci.ci_Source)) {
  322.                         if(trans->trans_Type == TYPE_RESPONSE) {
  323.                           FreeTransaction(trans);
  324.                         }
  325.                         else {
  326.                           do_transaction(trans);
  327.                         }
  328.                       }
  329.                     } while(msg != 0 || trans != 0);                    
  330.                   } while(ci.ci_IsOpen);
  331.                   out("\n");
  332.                 }
  333.               }
  334.               LoseEntity(ci.ci_Dest);
  335.             }
  336.             DeleteEntity(ci.ci_Source);
  337.           }
  338.           CloseLibrary(ServicesBase);
  339.         }
  340.         CloseLibrary(NIPCBase);
  341.       }
  342.       FreeSignal(signum);
  343.     }
  344.     DeleteMsgPort(ci.ci_Port);
  345.   }
  346.   if(retval) {
  347.     out("Login failed.\n");
  348.     SetIoErr(rc2);
  349.   }
  350.   return(retval);
  351. }
  352.  
  353. struct ActionNode {
  354.   struct MinNode      an_Node;
  355.   struct DosPacket   *an_Packet;
  356.   struct Transaction *an_Trans;
  357. };
  358.  
  359. void do_packet(struct DosPacket *dp)
  360.  
  361. {
  362.   struct ActionNode *an;
  363.   struct Transaction *trans;
  364.  
  365.   an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
  366.   while(an->an_Node.mln_Succ) {
  367.     if(an->an_Packet == dp) break;
  368.     an = (struct ActionNode *)(an->an_Node.mln_Succ);
  369.   }
  370.   if(an->an_Node.mln_Succ) {
  371.     trans = an->an_Trans;
  372.     if(ci.ci_IOStdReq) {
  373.       CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
  374.     }
  375.     *(LONG *)resp(trans,OFFS_RES1) = dp->dp_Res1;
  376.     *(LONG *)resp(trans,OFFS_RES2) = dp->dp_Res2;
  377.     ReplyTransaction(trans);
  378.     Remove((struct Node *)an);
  379.     FreeMem(an,sizeof(struct ActionNode));
  380.   }
  381.   FreeDosObject(DOS_STDPKT,dp);
  382. }
  383.  
  384. void do_transaction(struct Transaction *trans)
  385.  
  386. {
  387.   struct ActionNode *an;
  388.   struct DosPacket *dp;
  389.   struct Message *msg;
  390.  
  391.   if(trans->trans_Command == 0) {
  392.     an = (struct ActionNode *)AllocMem(sizeof(struct ActionNode),0);
  393.     if(an) {
  394.       dp = (struct DosPacket *)AllocDosObjectTags(DOS_STDPKT,TAG_DONE);
  395.       if(dp) {
  396.         dp->dp_Type = *(LONG *)req(trans,OFFS_ARG1);
  397.         switch(dp->dp_Type) {
  398.           case ACTION_READ:
  399.           case ACTION_WRITE:
  400.           case 2001: /* ACTION_FORCE */
  401.           case 2002: /* ACTION_STACK */
  402.           case 2003: /* ACTION_QUEUE */
  403.             dp->dp_Arg1 = 0;
  404.             dp->dp_Arg3 = *(LONG *)req(trans,OFFS_ARG2);
  405.             if(dp->dp_Type == ACTION_READ) {
  406.               dp->dp_Arg2 = (LONG)resp(trans,OFFS_RESPDATA);
  407.             }
  408.             else {
  409.               dp->dp_Arg2 = (LONG)req(trans,OFFS_REQDATA);
  410.             }          
  411.             break;
  412.           case ACTION_WAIT_CHAR:
  413.           case ACTION_SCREEN_MODE:
  414.           case 2004: /* ACTION_DROP */
  415.             dp->dp_Arg1 = *(LONG *)req(trans,OFFS_ARG2);
  416.             break;
  417.           default:
  418.             if(ci.ci_IOStdReq) {
  419.               CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
  420.             }
  421.             *(LONG *)resp(trans,OFFS_RES1) = 
  422.               (dp->dp_Type == ACTION_SEEK) ? -1 : DOSFALSE;
  423.             *(LONG *)resp(trans,OFFS_RES2) = ERROR_ACTION_NOT_KNOWN;
  424.             ReplyTransaction(trans);
  425.             FreeDosObject(DOS_STDPKT,dp);
  426.             FreeMem(an,sizeof(struct ActionNode));
  427.             return;
  428.         }
  429.         an->an_Packet = dp;
  430.         an->an_Trans = trans;
  431.         AddTail((struct List *)&(ci.ci_Actions),(struct Node *)an);
  432.         dp->dp_Port = ci.ci_Port;
  433.         PutMsg(ci.ci_Handler,dp->dp_Link);
  434.         return;
  435.       }
  436.       FreeMem(an,sizeof(struct ActionNode));
  437.     }
  438.   }
  439.   else {
  440.     an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
  441.     while(an->an_Node.mln_Succ) {
  442.       dp = an->an_Packet;
  443.       AbortPkt(ci.ci_Handler,dp);
  444.       if(ci.ci_IOStdReq) {
  445.         CopyMem(CONUNIT(ci),resp(trans,OFFS_CONUNIT),SIZE_CONUNIT);
  446.       }
  447.       if(dp->dp_Type == ACTION_READ || dp->dp_Type == ACTION_WRITE) {
  448.         *(LONG *)resp(an->an_Trans,OFFS_RES1) = -1;
  449.       }
  450.       else {
  451.         *(LONG *)resp(an->an_Trans,OFFS_RES1) = DOSFALSE;
  452.       }
  453.       *(LONG *)resp(an->an_Trans,OFFS_RES2) = ERROR_INVALID_LOCK;
  454.       ReplyTransaction(an->an_Trans);
  455.       an = (struct ActionNode *)(an->an_Node.mln_Succ);
  456.     }      
  457.     while(!IsListEmpty((struct List *)&(ci.ci_Actions))) {
  458.       WaitPort(ci.ci_Port);
  459.       while(msg = GetMsg(ci.ci_Port)) {
  460.         dp = (struct DosPacket *)(msg->mn_Node.ln_Name);
  461.         an = (struct ActionNode *)(ci.ci_Actions.mlh_Head);
  462.         while(an->an_Node.mln_Succ) {
  463.           if(an->an_Packet == dp) break;
  464.           an = (struct ActionNode *)(an->an_Node.mln_Succ);
  465.         }
  466.         if(an->an_Node.mln_Succ) {
  467.           Remove((struct Node *)an);
  468.           FreeMem(an,sizeof(struct ActionNode));
  469.         }
  470.         FreeDosObject(DOS_STDPKT,dp);
  471.       }
  472.     }  
  473.     ReplyTransaction(trans);
  474.     ci.ci_IsOpen = FALSE;
  475.   }   
  476. }
  477.